<template>
  <div>
    <div :id="tableId" class="mrpTable">
      <table class="relative w-full overflow-scroll" style="table-layout: fixed">
        <!-- 头部 -->
        <tr class="sticky-header">
          <template v-for="(item, index) in _responOption" :key="index">
            <th
              v-if="item.show"
              :class="'table-cell defaultTC defaultTS tableBC  tableHeaderBGC'"
              :style="{
                height: SIZEMAP[_responSize].size + 'px',
                width: item.w ? item.w : ''
              }"
            >
              <!-- 多选择框插槽 -->
              <slot v-if="_responOption[index].key == 'select'" name="selectAll" />
              <div class="flex items-center justify-center">
                <!-- 自定义头部插槽 name为 th-{item.key} -->
                <template v-if="item.customHeader">
                  <slot :name="'th-' + item.key" :index="index" :item="item" />
                </template>
                <template v-else>
                  {{ item.title }}
                  <span v-if="item.unit" class="markTC">({{ item.unit }})</span>
                </template>
              </div>
              <!-- header：数组 子级嵌套头部 -->
              <div v-if="_responOption[index].headerChild">
                <div class="h-2 flex items-center">
                  <span class="bg-[#d9d9d9] h-[1px] w-full" />
                </div>
                <div class="flex items-center justify-between h-1/2">
                  <div v-for="(e, i) in _responOption[index].headerChild" :key="i" :style="{ width: e.w ? e.w : '' }">
                    {{ e.title }}
                    <span v-if="e.unit" class="markTC">{{ e.unit }}</span>
                  </div>
                </div>
              </div>
            </th>
          </template>
        </tr>
        <!-- 主体 -->
        <template v-if="data.length !== 0">
          <template v-for="(dItem, dIndex) in data" :key="dItem?.id">
            <!-- 是否显示当前行。用于表格折叠 -->
            <tr
              v-if="!isFold || dItem?.fold"
              :key="dItem?.id"
              :class="[isClickItem && dItem?.id === clickItemId ? 'active_click_td' : '']"
              @click="onClickItem(dItem)"
            >
              <template v-for="(oItem, oIndex) in _responOption" :key="oIndex">
                <td
                  v-if="
                    oItem.show &&
                    cellMergeHandle(dItem, dIndex, oItem, oIndex, 'COL') !== 0 &&
                    cellMergeHandle(dItem, dIndex, oItem, oIndex, 'ROW') !== 0
                  "
                  :colspan="cellMergeHandle(dItem, dIndex, oItem, oIndex, 'COL')"
                  :rowspan="cellMergeHandle(dItem, dIndex, oItem, oIndex, 'ROW')"
                  class="table-cell defaultTC defaultTS tableBC"
                  :style="{
                    height: SIZEMAP[_responSize].size + 'px'
                  }"
                >
                  <!-- 序号 -->
                  <div v-if="['index'].includes(oItem.key)">
                    {{ currentPages - 1 == 0 ? dIndex + 1 : (currentPages - 1) * pageSize + dIndex + 1 }}
                  </div>
                  <!-- 金额格式化 -->
                  <div v-else-if="oItem.precision">
                    {{ numFormat(dItem[oItem.key]) }}
                  </div>
                  <!-- 日期格式化 -->
                  <div v-else-if="oItem.dateFormAt">
                    {{ dItem[oItem.key] ? dayjs(dItem[oItem.key]).format(oItem.dateFormAt) : '' }}
                  </div>
                  <!-- 图片数据特殊处理 -->
                  <div
                    v-else-if="['pictures', 'pictureUrls'].includes(oItem.key)"
                    class="flex justify-center items-center relative"
                  >
                    <CImageView :data="dItem[oItem.key]" />
                  </div>
                  <!-- 插槽处理 -->
                  <!-- 按钮使用slot-->
                  <slot
                    v-else-if="['buttonSlot', 'clickSlot', 'select'].includes(oItem.key)"
                    :id="dItem?.id"
                    :name="oItem.key"
                    :item="dItem"
                  />
                  <!-- 按钮使用slot-->
                  <slot v-else-if="oItem.custom" :id="dItem?.id" :name="oItem.key" :item="dItem" />
                  <!-- 常规处理 -->
                  <div v-else>
                    {{
                      oItem.formAt
                        ? oItem.formAt({
                            v: dItem[oItem.key],
                            o: dItem,
                            th: oItem
                          })
                        : dItem[oItem.key]
                    }}
                  </div>
                </td>
              </template>
            </tr>
          </template>
        </template>
        <template v-else>
          <TableFooterIcon />
        </template>
      </table>
      <CTableControl
        v-if="isShowControl"
        v-model:table-option="_responOption"
        :density="_responSize"
        @change-density="onChangeDensity"
        @change-table-col="onChangeControl"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, toRaw } from 'vue'
import dayjs from 'dayjs'
import { numFormat } from 'iv-npm/packages/shared'

import CTableControl from './CTableControl.vue'
import CImageView from './CImageView.vue'
import { TableFooterIcon } from './icon'

import { SIZEMAP, defaultProps } from './option'
import type { Option, ThOption } from './option'

/**
 * 组件定义
 * */
interface TableEmit {
  (e: 'clickItem', item: any): void
  (e: 'changeOption', value?: ThOption[]): void
  (e: 'update:clickId', value?: string): void
}

const props = withDefaults(defineProps<Option>(), defaultProps)
const emit = defineEmits<TableEmit>()

/**
 * 初始化数据
 * */

/**
 * 点击单元格功能
 * */
const clickItemId = computed({
  get() {
    return props.clickId
  },
  set(value) {
    emit('update:clickId', value)
  }
})
const onClickItem = (item: any) => {
  if (props.isClickItem) {
    clickItemId.value = item?.id === clickItemId.value ? (props.isMustSelected ? item?.id : undefined) : item?.id
    emit('clickItem', item)
  }
}

/**
 * 控件功能
 * */
// 列表显示与隐藏
const _responOption = ref(props.option)
const onChangeControl = (val?: ThOption[]) => {
  emit('changeOption', toRaw(val))
}
// 更改尺寸
const _responSize = ref(props.size)
const onChangeDensity = (key: keyof typeof SIZEMAP) => {
  _responSize.value = key
}

/**
 * 单元格合并
 * */
const cellMergeHandle = (dItem: any, dIndex: number, oItem: ThOption, oIndex: number, type: 'COL' | 'ROW') => {
  const { colspanHandle, rowspanHandle } = oItem
  const paramsData = {
    rowIndex: dIndex,
    columnIndex: oIndex,
    row: dItem,
    column: oItem
  }
  if (type === 'COL') {
    return colspanHandle ? colspanHandle(paramsData) : undefined
  } else if (type === 'ROW') {
    return rowspanHandle ? rowspanHandle(paramsData) : undefined
  }
}
</script>

<style scoped>
.active_click_td {
  background-color: #97d2fd;
}
table {
  border-collapse: collapse;
}
.mrpTable {
  position: relative;
  padding-bottom: 20px;
}
.table-cell {
  height: 60px;
  border: 1px solid #bd9e55;
  padding: 5px;
  word-break: break-all;

  font-weight: 400;
  text-align: center;
}
.sticky-header {
  position: sticky;
  top: -1px;
  z-index: 1;
}
</style>
